#include "Comm.hpp"
#include <wait.h>
#include <sys/wait.h>
#include "Log.hpp"

// static void getMessage(int fd)
// {
//     //这里要从客户端进程处接受消息
//     char buffer[SIZE];
//     while(true)
//     {
//         memset(buffer,'\0',strlen(buffer));
//         ssize_t s=read(fd,buffer,strlen(buffer));
//         if(s > 0)
//         {
//             cout<<"["<<getpid()<<"] client say:"<<buffer<<endl;
//             break;
//         }
//         else if(s == 0)
//         {
//             cerr<<"["<<getpid()<<"]"<<"read end of file"<<endl;
//             break;
//         }
//         else
//         {
//             perror("read");
//             break;
//         }
//     }
// }


// int main()
// {
//     if(mkfifo("mypipe",MODE) < 0)
//     {
//         perror("mkfifo");
//         exit(-1);
//     }
//     Log("创建管道文件成功",Debug)<<"step 1"<<endl;
//     int fd=open("mypipe",O_RDONLY);
//     if(fd < 0)
//     {
//         perror("open");
//         exit(2);
//     }
//     Log("打开管道文件成功",Debug)<<"step 2"<<endl;
    
//     for(int i=0;i<5;i++)
//     {
//         pid_t id=fork();
//         if(id == 0)
//         {
//             perror("fork()");
//             getMessage(fd);
//             exit(2);
//         }
//     }
//     for(int i=0;i<5;i++)
//     {
//         waitpid(-1,nullptr,0);
//     }
//     close(fd);
//     Log("关闭管道文件成功",Debug)<<"step 3"<<endl;
//     unlink("mypipe");
//     Log("删除管道文件成功",Debug)<<"step 4"<<endl;
//     return 0;
// }
// static void getMessage(int fd)
// {
//     if(open(ipcPath.c_str(),O_RDONLY) < 0)
//     {
//         perror("open");
//         exit(-1);
//     }
//     char buffer[1024];
//     while(true)
//     {
//         ssize_t s=read(fd,buffer,strlen(buffer));
//         if(s > 0)
//         {
//             cout<<"cilent say:"<<buffer<<endl;
//         }
//         else if(s == 0)
//         {
//             cout<<"read enf of file"<<endl;
//         }
//         else
//         {
//             perror("open");
//             exit(-1);
//         }
//     }
// }

// int main()
// {
//     Log("创建管道成功",Debug)<<"step 1"<<endl;
//     if(mkfifo(ipcPath.c_str(),MODE) < 0)
//     {
//         perror("mkfifo");
//         exit(-1);
//     }
//     //客户端父进程要在这里等待消息，子进程要负责去处理消息
//     Log("打开管道成功",Debug)<<"step 2"<<endl;
//     int fd=open(ipcPath.c_str(),O_RDONLY);
//     if(fd < 0)
//     {
//         perror("open");
//         exit(-1);
//     }
//     char buffer[1024]={0};
//     for(int i=0;i<5;i++)
//     {
//         pid_t id=fork();
//         if(id == 0)
//         {
//             perror("fork()");
//             getMessage(fd);
//             exit(-1);
//         }
//     }
//     for(int i=0;i<5;i++)
//     {
//         waitpid(-1,nullptr,0);
//     }
//     close(fd);
//     Log("关闭管道成功",Debug)<<"step 3"<<endl;
//     unlink(ipcPath.c_str());
//     Log("删除管道成功",Debug)<<"step 4"<<endl;
// }
/*
共享内存是最快的IPC方式，一旦这样的内存映射到共享内它的进程的地址
空间，这些进程间数据传递不再涉及到内存，换句话说是进程不再通过
执行进入内核的系统调用来传递彼此的数据

int shmget(key_t key,size_t size,int shmflag);
key_t key:这个共享内存的字段
size:共享内存大小
shmflag:权限标志符
返回值：成功返回一个整数，即该共享内存的标识码，失败返回-1

void* shmat(int shmid,const void* shmaddr,int shmflag);
shmid:共享内存的标识符
shmaddr:指定连接的地址
shmflag:
返回值：成功返回一个指针，指向共享内存的第一个字节，失败返回-1

int shmdt(const void* shmaddr)
功能：将共享内存段与当前进程脱离，注意将共享内存与当前的进程
分离不代表已经将共享内存删除

//成功返回0失败返回-1
int shmctl(int shmid,int cmd,struct shmid_ds* buf)

*/
// 客户端要写入信息，而服务器要读取数据
//  static void getMessage(int fd)
//  {
//      char buffer[SIZE];
//      while(true)
//      {
//          memset(buffer,'\0',sizeof(buffer));
//          ssize_t s = read(fd,buffer,strlen(buffer));
//          if(s > 0)
//          {
//              cout<<"["<<getpid()<<"] client say:"<<buffer<<endl;
//          }
//          else if(s == 0)
//          {
//              cerr<<"["<<getpid()<<"]"<<"read end of file"<<endl;
//              break;
//          }
//          else
//          {
//              perror("read");
//              break;
//          }
//      }
//  }
//  static void getMessage(int fd)
//  {
//      int ret=open(ipcPath.c_str(),O_RDONLY);
//      if(ret < 0)
//      {
//          perror("open");
//          exit(-1);
//      }
//      char buffer[1024]={0};
//      ssize_t s=read(fd,buffer,strlen(buffer));
//      if(s > 0)
//      {
//          cout<<"["<<getpid()<<"]"<<buffer<<endl;
//          break;
//      }
//      else if(s == 0)
//      {
//          cout<<"read end of file"<<endl;
//          break;
//      }
//      else
//      {
//          perror("read");
//          break;
//      }
//  }
static void getMessage(int fd)
{
    if (open(ipcPath.c_str(), O_RDONLY) < 0)
    {
        perror("open");
        exit(-1);
    }
    while (true)
    {
        char buffer[1024] = {0};
        ssize_t s = read(fd, buffer, strlen(buffer));
        if (s > 0)
        {
            cout<<"["<<getpid()<<"]"<<buffer<<endl;
            break;
        }
        else if(s == 0)
        {
            cout<<"read end of file"<<endl;
            break;
        }
        else
        {
            perror("read");
            exit(-1);
        }
    }
}

int main()
{
    if (mkfifo(ipcPath.c_str(), MODE) < 0)
    {
        perror("mkfifo");
        exit(-1);
    }
    // 当管道打开以后父子进程之间就可以
    int fd = open(ipcPath.c_str(), O_RDONLY);
    if (fd < 0)
    {
        perror("open");
        exit(-1);
    }
    for (int i = 0; i < 5; i++)
    {
        pid_t id = fork();
        if (id == 0)
        {
            getMessage(fd);
            exit(-1);
        }
    }
    for (int i = 0; i < 5; i++)
    {
        waitpid(-1, nullptr, 0);
    }
    close(fd);
    unlink(ipcPath.c_str());
    return 0;
}
// int main()
// {
//     int n=mkfifo(ipcPath.c_str(),MODE);
//     if(n < 0)
//     {
//         perror("mkfifo");
//         exit(-1);
//     }
//     int ret=open(ipcPath.c_str(),O_RDONLY)
//     {
//         perror("open");
//         exit(-1);
//     }
//     int nums=3;
//     for(int i=0;i<nums;i++)
//     {
//         pid_t id=fork();
//         if(id == 0)
//         {
//             getMessage(fd);
//             exit(1);
//         }
//     }
//     for(int i=0;i<nums;i++)
//     {
//         waitpid(-1,nullptr,0);
//     }
//     close(fd);
//     unlink(ipcPath.c_str());
//     return 0;
// }
// static void getMessage(int fd)
// {
//     char buffer[SIZE];
//     while(true)
//     {
//         memset(buffer,'\0',strlen(buffer));
//         ssize_t s=read(fd,buffer,strlen(buffer));
//         if(s < 0)
//         {
//             perror("read");
//             break;
//         }
//         else if(s > 0)
//         {
//             cout<<"["<<getpid()<<"] client say:"<<buffer<<endl;
//             break;
//         }
//         else
//         {
//             cout<<"read end of file"<<endl;
//             break;
//         }
//     }
// }

// int main()
// {
//     return 0;
//     if(mkfifo(ipcPath.c_str(),MODE) < 0)
//     {
//         perror("mkfifo");
//         exit(-1);
//     }
//     Log("创建管道文件成功",Debug)<<"step 1"<<endl;
//     int fd=open(ipcPath.c_str(),O_RDONLY);
//     if(fd < 0)
//     {
//         perror("open");
//         exit(-1);
//     }
//     Log("打开管道文件成功",Debug)<<"step 2"<<endl;
//     int nums=3;
//     for(int i=0;i<nums;i++)
//     {
//         pid_t id=fork();
//         if(id == 0)
//         {
//             getMessage(fd);
//             exit(1);
//         }
//     }
//     for(int i=0;i<nums;i++)
//     {
//         waitpid(-1,nullptr,0);
//     }
//     close(fd);
//     Log("关闭管道文件成功呢",Debug)<<"step 3"<<endl;
//     unlink(ipcPath.c_str());
//     Log("删除管道文件成功",Debug)<<"step 4"<<endl;
//     return 0;
// }
// int main()
// {
//     if(mkfifo(ipcPath.c_str(),MODE) < 0)
//     {
//         perror("mkfifo");
//         exit(-1);
//     }
//     Log("创建管道文件",Debug)<<"step 1"<<endl;
//     int fd=open(ipcPath.c_str(),O_RDONLY);
//     if(fd < 0)
//     {
//         perror("open");
//         exit(-1);
//     }
//     Log("打开管道文件",Debug)<<"step 2"<<endl;

//     int count=3;
//     for(int i=0;i<count;i++)
//     {
//         pid_t id=fork();
//         if(id == 0)
//         {
//             getMessage(fd);
//             exit(0);
//         }
//     }
//     for(int i=0;i<count;i++)
//     {
//         waitpid(-1,nullptr,0);
//     }
//     close(fd);
//     Log("关闭管道文件成功",Debug)<<"step 3"<<endl;
//     unlink(ipcPath.c_str());
//     Log("删除管道文件成功",Debug)<<endl;
//     return 0;
// }